package orders

import (
	"cloud_android_backend/pkg/config"
	"cloud_android_backend/pkg/models/orders"
	payment2 "cloud_android_backend/pkg/modules/payment"
	"fmt"
	"github.com/golang/glog"
	"modules.tenxcloud.com/common/composite"
	"os"
	"time"
)

type CreateOrderReq struct {
	Amount        float64 `json:"amount" `
	PaymentSource string  `json:"payment_source" `
	Remark        string  `json:"remark"`
	TransType     int     `json:"trans_type" `
	ClientIp      string  `json:"client_ip"`
	DeviceInfo    string  `json:"device_info"`
}
type CreateOrderResp struct {
	OrderId    int64  `json:"order_id"`
	TradeNo    string `json:"trade_no"`
	Data       string `json:"data"`
	ResultType string `json:"result_type"`
}

func CreateReChargeOrderAndPay(params CreateOrderReq, userId string) (CreateOrderResp, error) {
	var Response CreateOrderResp
	if params.PaymentSource != "wechat" && params.PaymentSource != "alipay" {
		return Response, fmt.Errorf("payment source not support")
	}
	orderGenerator := NewBaseOrderGenerator("RECHARGE")
	tradeNo := orderGenerator.Generate()
	order := &orders.Orders{
		TradeNo: tradeNo,
		Amount:  params.Amount,
		Remark:  params.Remark,

		TransType:     int(orders.TransType_Recharge),
		UserId:        userId,
		Status:        int(orders.OrderStatus_Pending),
		CreatedAt:     time.Now(),
		UpdatedAt:     time.Now(),
		PaymentSource: params.PaymentSource,
		ClientIp:      params.ClientIp,
		DeviceInfo:    params.DeviceInfo,
		OrderType:     int(orders.OrderTypeRecharge),
	}
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get orm failed, error %v", err)
		return Response, err
	}
	err = order.Create(db)
	if err != nil {
		glog.Errorf("create order failed:err %v", err)
		return Response, err
	}
	if config.Config == nil {
		config.InitConfig()
	}
	Config := config.Config
	var payment payment2.UniCreateOrder
	domain := os.Getenv("DOMAIN")
	if domain == "" {
		domain = "https://clp.jtcloud.icu"
	}
	switch params.PaymentSource {
	case "wechat":
		payment = &payment2.WechatPay{
			Amount:          params.Amount,
			Description:     "余额充值",
			OutTradeNo:      tradeNo,
			Remark:          params.Remark,
			WechatPayConfig: Config.WechatPay,
		}
	case "alipay":
		payment = &payment2.Alipay{
			Amount:      params.Amount,
			Description: "余额充值",
			OutTradeNo:  tradeNo,
			Remark:      params.Remark,
			Subject:     "余额充值",
			Url:         domain + "/wallet",
		}
	}
	result, err := payment.Payment()
	if err != nil {
		glog.Errorf("payment failed:err %v", err)
		return Response, err
	}
	resutlType := payment.GetResultType()
	Response = CreateOrderResp{
		Data:       result,
		ResultType: string(resutlType),
		TradeNo:    tradeNo,
		OrderId:    order.Id,
	}

	return Response, nil
}

type OrderStatusResp struct {
	OrderId       int64   `json:"order_id"`
	Status        string  `json:"status"`
	Actual        float64 `json:"actual"`
	TradeNo       string  `json:"trade_no"`
	PayTime       string  `json:"pay_time"`
	TransactionId string  `json:"transaction_id"`
	OrderType     int     `json:"order_type"`
}

func GetOrderStatus(orderId int64, tradeNo string) (OrderStatusResp, error) {
	var orderstatus OrderStatusResp
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get order status failed:err %v", err)
		return orderstatus, err
	}
	orderModel := orders.Orders{Id: orderId, TradeNo: tradeNo}
	if tradeNo != "" {
		if err := orderModel.FindByTradeNo(db); err != nil {
			glog.Errorf("查询订单失败: %v", err)
			return orderstatus, err
		}
	} else {
		if err := orderModel.GetById(db); err != nil {
			glog.Errorf("查询订单失败: %v", err)
			return orderstatus, err
		}
	}

	orderstatus = OrderStatusResp{
		OrderId: orderModel.Id,
		PayTime: orderModel.PayTime.Format("2006-01-02 15:04:05"),
		//Status:   orders.OrderStatus(orderModel.Status).String(),
		TradeNo:   orderModel.TradeNo,
		Actual:    orderModel.ActualAmount,
		OrderType: orderModel.OrderType,
	}
	switch orderModel.Status {
	case int(orders.OrderStatus_Pending):
		orderstatus.Status = "pending"
	case int(orders.OrderStatus_Success):
		orderstatus.Status = "success"
	case int(orders.OrderStatus_Cancel), int(orders.OrderStatus_Failed):
		orderstatus.Status = "failed"
	default:
		orderstatus.Status = "pending"
	}
	return orderstatus, nil
}

func GetOrderList(userId string, offset int, limit int, search map[string]interface{}) ([]orders.Orders, int, error) {
	var orderList []orders.Orders
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get database connection failed, %s", err)
		return orderList, 0, err
	}
	OrderModel := &orders.Orders{}
	total := 0
	orderList, total, err = OrderModel.GetList(db, userId, offset, limit, search)
	if err != nil {
		glog.Errorf("get order list failed, %s", err)
		return orderList, total, err
	}
	return orderList, total, err
}

func Payment(orderId int64) (CreateOrderResp, error) {
	var response CreateOrderResp
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get orm failed, error %v", err)
		return response, err
	}
	if orderId == 0 {
		return response, fmt.Errorf("order id is empty")
	}
	OrderModel := &orders.Orders{Id: orderId}
	err = OrderModel.GetById(db)
	if err != nil {
		return response, err
	}
	if config.Config == nil {
		config.InitConfig()
	}
	Config := config.Config
	var payment payment2.UniCreateOrder

	description := "余额充值"
	switch OrderModel.OrderType {
	case int(orders.OrderTypeInstance):
		description = "云机购买"
	case int(orders.OrderTypeRecharge):
		description = "余额充值"
	}
	switch OrderModel.PaymentSource {
	case "wechat":
		payment = &payment2.WechatPay{
			Amount:      1, //OrderModel.Amount*100,
			Description: description,
			OutTradeNo:  OrderModel.TradeNo,
			//Remark:          params.Remark,
			WechatPayConfig: Config.WechatPay,
		}
	case "alipay":
		payment = &payment2.Alipay{
			Amount:      0.01, //OrderModel.Amount,
			Description: description,
			OutTradeNo:  OrderModel.TradeNo,
			//Remark:      .Remark,
			Subject: description,
		}
	}
	result, err := payment.Payment()
	if err != nil {
		glog.Errorf("payment failed:err %v", err)
		return response, err
	}
	resutlType := payment.GetResultType()
	response = CreateOrderResp{
		Data:       result,
		ResultType: string(resutlType),
		TradeNo:    OrderModel.TradeNo,
		OrderId:    OrderModel.Id,
	}
	return response, nil
}

func GetOrderById(orderId int64) (orders.Orders, error) {
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get database connection failed, %s", err)
		return orders.Orders{}, err
	}
	orderModel := orders.Orders{Id: orderId}
	err = orderModel.GetById(db)
	if err != nil {
		glog.Errorf("get order failed, %s", err)
		return orders.Orders{}, err
	}
	return orderModel, nil
}

func GetOrderByStatusAndCatId(catId int, userId string) (orders.Orders, error) {
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Errorf("get database connection failed, %s", err)
		return orders.Orders{}, err
	}
	orderModel := orders.Orders{}
	orderInfo, err := orderModel.GetOrderByStatusAndUserIdAndCatId(db, int(orders.OrderStatus_Pending), userId, catId)
	if err != nil {
		glog.Errorf("get order failed, %s", err)
		return orders.Orders{}, err
	}
	return orderInfo, err

}
